#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <errno.h>
#include <signal.h>


#include "proto.h"


#define MAXSPAREPRO		10
#define MINSPAREPRO		5
#define	MAXPRO			20
#define SIG_NOTIFY		SIGUSR2



/*池状态*/
enum
{
	POOL_INIT=1,
	POOL_RUN,
	POOL_ADD,
	POOL_DEL,
	POOL_ERR,
	POOL_EOT
};

/*进程状态*/
enum
{
	PRO_STATE_IDEL=1,
	PRO_STATE_BUSY
};

/*进程结构体*/
struct pro_st
{
	pid_t pid;
	int state;
};

/*池结构体*/
struct pool_st
{
	pid_t pid;
	int state;
	int idle_count;
	int busy_count;
	int _errno_;
	char * errstr;
};

//static int idle_count=0;
//static int busy_count=0;

static sigset_t saveset;

/*进程要执行函数*/
static int (*p)(void *,int);
/*参数*/
static void * pv;
/*参数个数*/
static int pc;

static struct pool_st pool;

static struct pro_st * propool=NULL;

static void notice_ppid(int pos,int state)
{
	propool[pos].state = state;
	kill(pool.pid,SIG_NOTIFY);
}

void notice_ppid_IDEL(const int pos)
{
	if(pos<0 || pos>MAXPRO)
		return;
	pool.idle_count++;
	pool.busy_count--;
	notice_ppid(pos,PRO_STATE_IDEL);
}

void notice_ppid_BUSY(const int pos)
{
	if(pos<0 || pos>MAXPRO)
		return;
	pool.idle_count--;
	pool.busy_count++;
	notice_ppid(pos,PRO_STATE_BUSY);
}
/*状态驱动*/
static int dirver();

/*初始化*/
static int module_load();

/*添加一个进程*/
static int add_pro();

/*减少一个进程*/
static int del_pro();


static int add_pro(int pos)
{
	pid_t pid;
	pid = fork();
	if(pid<0)//
	{
		
	}
	if(pid==0)
	{
	
	}
	if(pid>0)
	{
		
	}
}

static int del_pro()
{


}

int pool_free()
{
	pool.state = POOL_EOT;
}

static int dirver()
{
	int rtn=0;
	switch (pool.state)
	{
		case POOL_INIT:
			rtn=module_load();
			break;
		case POOL_ADD:
			rtn=add_pro();
			break;
		case POOL_DEL:
			rtn=del_pro();
			break;
		case POOL_ERR:
			pool.state = POOL_EOT;
			break;
		case POOL_EOT:
			//free()
			sigprocmask(SIG_SETMASK,&saveset,NULL);
			break;
		default:
			break;
	}
	return	rtn=0;
}


static int module_load()
{
	propool = mmap(NULL,sizeof(struct pro_st)*MAXPRO,PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0);
	if(propool == MAP_FAILED)
	{
		pool._errno_= errno;
		pool.errstr = "mmap()";
		pool.state = POOL_ERR;
	}
	else
	{
		int i=0;
		pool.state = POOL_RUN;
		for(i=0;i<MINSPAREPRO;i++)
		{
			int r = add_pro();
			if(r<0)
			{
				//pool.state = POOL_ERR;
				break;
			}
		}
	}
}


int pool_run(int (*fun)(void *,int),void * argv,int argc)
{
	p=fun;
	pc=argc;
	pv=argv;
//	(*p)(pv,pc);
//
	struct sigaction sa,osa;
	sa.sa_handler = SIG_IGN;
	sigemptyset(&sa.sa_mask);
	sa.sa_flags = SA_NOCLDWAIT;
	sigaction(SIGCHLD,&sa,&osa);

	sa.sa_handler = usr2_handler;
	sigemptyset(&sa.sa_mask);
	sa.sa_flags = 0;
	sigaction(SIG_NOTIFY,&sa,&osa);

	pool.state=POOL_INIT;
	pool.idle_count=0;
	pool.busy_count=0;
	pool.pid = getpid();

	sigset_t set,oset;
	sigemptyset(&set);
	sigemptyset(&saveset);
	sigaddset(&set,SIG_NOTIFY);
	sigprocmask(SIG_UNBLOCK,&set,&saveset);
	sigprocmask(SIG_BLOCK,&set,&oset);
	while(1)
	{
		sigsuspend(&oset);`
		dirver();
	}
	//sigprocmask(SIG_SETMASK,&oset,NULL);
	sigprocmask(SIG_SETMASK,&saveset,NULL);
}

int pool_free()
{
	
}
